/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.worldscale.xp.wslib.im.jabber.impl;

import java.io.InputStream;
import java.io.OutputStream;
import net.worldscale.xp.wslib.im.jabber.JabberClient;
import net.worldscale.xp.wslib.im.jabber.JabberID;
import net.worldscale.xp.wslib.wsxml.WsXML;
import net.worldscale.xp.wslib.wsxml.sax.SaxHandler;
import net.worldscale.xp.wslib.wsxml.sax.SaxParser;
import org.w3c.dom.Element;

/**
 *
 * @author Kun
 */
final class WorkSession {

    private final UserSession mParentSession;
    private boolean mIsClosed = false;
    private JabberClient.Dispatcher mDispatcher;
    private MyAbstractConnection mConn;
    private InputStream mIS;

    public WorkSession(UserSession parent) {
        mParentSession = parent;
    }

    public void proc() {
        System.out.println(this + ".proc - begin");
        MyAbstractConnection conn = null;
        InputStream is = null;
        OutputStream os = null;
        try {
            final JabberClient.LoginContext lc = this.getParentSession().getLoginContext();
            if (lc.isUseSSL()) {
                conn = MySSLConnection.open(lc.getServer(), lc.getPort());
            } else {
                conn = My_TCP_TLS_Connection.open(lc.getServer(), lc.getPort());
                // conn = MyTCPConnection.open(lc.getServer(), lc.getPort());
            }
            mConn = conn;
            is = (conn.openInputStream());
            mIS = is;
            os = (conn.openOutputStream());
            // final MyTLSInputStreamProxy inProxy = new MyTLSInputStreamProxy(conn.openInputStream());
            // final MyTLSOutputStreamProxy outProxy = new MyTLSOutputStreamProxy(conn.openOutputStream());
            // is = inProxy;
            // os = outProxy;
            //
            final ImplJabberDispatcher disp = new ImplJabberDispatcher(os);
            final SaxParser parser = WsXML.getInstance().getSaxParserFactory().newParser();
            final JabberClient.StreamListener sl = new JabberRT(this, disp);
            final SaxHandler h = new ImplJabberReceiver(sl);
            //
            this.mDispatcher = disp;
            disp.setListener(_getStanzaListener());
            // this.mInputProxy = inProxy;
            // this.mOutputProxy = outProxy;
            //
            disp.openStream(lc.getJID().getHost());
            parser.parse(is, h);
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.mDispatcher = null;
        this.mConn = null;
        //       this.mInputProxy = null;
        //     this.mOutputProxy = null;
        try {
            if (os != null) {
                os.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (is != null) {
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(this + ".proc - end");
    }

    private ImplJabberDispatcher.StanzaListener _getStanzaListener() {
        return new ImplJabberDispatcher.StanzaListener() {

            public void onStanza(Element stanza) {
                _onSendStanza(stanza);
            }
        };
    }

    private void _onSendStanza(Element stanza) {
        final String tag = stanza.getTagName();
        if ("message".equals(tag)) {
            this.mParentSession.getMessageList().add(stanza);
            this.mParentSession.getParentSession().getEventRouter().onStanza(stanza);
        }
    }

    public void close() {
        this.mIsClosed = true;
        try {
            this.mDispatcher.closeStream();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            this.mIS.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public UserSession getParentSession() {
        return this.mParentSession;
    }
    private int mPhase = JabberClient.PHASE_LOGIN;

    public int getPhase() {
        return mPhase;
    }

    public void setPhase(final int newPhase) {
        final int oldPhase = this.mPhase;
        this.mPhase = newPhase;
        this.mParentSession.getParentSession().getEventRouter().onPhaseChanged(oldPhase, newPhase);
    }
    private JabberID mFullJID;

    public JabberID getFullJabberID() {
        return this.mFullJID;
    }

    public void setFullJabberID(JabberID jid) {
        this.mFullJID = jid;
    }

    public void startTLS() {
    }

    public JabberClient.Dispatcher getDispatcher() {
        return this.mDispatcher;
    }
}
